﻿using Simple.BasicNet.Core;
using Simple.BasicNet.Core.Handle;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/*********************************************************
 * 命名空间 App.Extension
 * 接口名称 IDTProtocolPack
 * 开发人员：11920
 * 创建时间：2023/4/17 13:12:01
 * 描述说明：
 * 更改历史：
 * 
 * *******************************************************/
namespace App.Extension
{
	public class IDTProtocolPack
	{
		public static readonly byte[] Head = new byte[2] { 0xA8, 0x30 };

		public static readonly byte[] Tail = new byte[2] { 0x3E, 0x24 };

		private static byte [] InitPack(int len,int commandId,eReceivePackType ReceivePackType)
		{
			if (len<7)
			{
				throw new ArgumentException("长度必须大7!");
			}
			byte[] buffer=new byte[len];
			Array.Copy(Head,0,buffer, 0, 2);
			buffer[2] = (byte)commandId;
			buffer[3] = (byte)((int)ReceivePackType & 0xFF);
			return buffer;

		}

		#region reply
		/// <summary>
		/// login
		/// </summary>
		/// <param name="commandId"></param>
		/// <param name="ReceivePackType"></param>
		/// <param name="IpAddress"></param>
		/// <param name="Port"></param>
		/// <param name="updateflag"></param>
		/// <returns></returns>
		public static byte[] LoginReply(int commandId,eReceivePackType ReceivePackType, string IpAddress,int Port, int updateflag = 0)
		{
			byte[] buffer =InitPack(34,commandId,ReceivePackType) ;//new byte[34];
			buffer[4] = (byte)(updateflag & 0xFF);
			Array.Copy(IpAddress.IPToBytes(), 0, buffer, 5, 4);
			Array.Copy(Port.IntToBytes(), 2, buffer, 9, 2);
			Array.Copy(DateTime.Now.CurrentTimeToBytes(), 0, buffer, 11, 6);
			Array.Copy(DateTime.Now.CurrentDateToBytes(), 0, buffer, 17, 6);
			//token暂不设置 8byte
			//获取校验和
			CompletePack(buffer);
			return buffer;
		}
		/// <summary>
		/// heart
		/// </summary>
		/// <param name="CommandStatus"></param>
		/// <param name="commandId"></param>
		/// <returns></returns>
		public static byte[] HeartReply(int commandId, eReceivePackType ReceivePackType)
		{
			byte[] buffer = InitPack(7,commandId,ReceivePackType);//new byte[7];
			CompletePack(buffer);
			return buffer;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="commandId"></param>
		/// <param name="ReceivePackType"></param>
		/// <param name="json"></param>
		/// <returns></returns>
		public static byte[] ReceiveDeviceInfoReply(int commandId, eReceivePackType ReceivePackType, string json)
		{
			byte[] dataBuffer = Encoding.UTF8.GetBytes(json);
			byte[] dataLength = BitConverter.GetBytes(dataBuffer.Length);
			Array.Reverse(dataLength);
			byte[] buffer = InitPack(dataBuffer.Length + 9,commandId,ReceivePackType);// new byte[dataBuffer.Length + 9];
			Array.Copy(dataLength, 2, buffer, 4, 2);
			Array.Copy(dataBuffer, 0, buffer, 6, dataBuffer.Length);
			CompletePack(buffer);
			return buffer;
		}


		public static byte[] VersionUpgradeReply(int commandId, eReceivePackType ReceivePackType, int totalSize, int totalPackNum,string firmwareVersion)
		{
			byte[] buffer = InitPack(21,commandId,ReceivePackType);//new byte[21];
			
			Array.Copy(totalSize.numToByte(4), 0, buffer, 4, 4);
			Array.Copy(totalPackNum.numToByte(2), 0, buffer, 8, 2);

			var versionByte = Encoding.UTF8.GetBytes(firmwareVersion == null ? "" : firmwareVersion);
			Array.Copy(versionByte, 0, buffer, 10, 8);
			//获取校验和
			CompletePack(buffer);
			return buffer;
		}

		public static byte[] VersionUpgradeDataReply(int commandId, eReceivePackType ReceivePackType,string firmwareVersion,int totalPackNum, int currentPackNum, int currentPackDataLength, byte[] currentPackData)
		{
			byte[] buffer = InitPack(23 + currentPackDataLength, commandId, ReceivePackType); //new byte[23 + currentPackDataLength];
			var versionByte = Encoding.UTF8.GetBytes(firmwareVersion);
			Array.Copy(versionByte, 0, buffer, 4, 8);
			Array.Copy(totalPackNum.numToByte(2), 0, buffer, 12, 2);
			Array.Copy(currentPackNum.numToByte(2), 0, buffer, 14, 2);
			Array.Copy(currentPackDataLength.numToByte(4), 0, buffer, 16, 4);
			Array.Copy(currentPackData, 0, buffer, 20, currentPackDataLength);
			//获取校验和
			CompletePack(buffer);
			return buffer;
		}

		public static byte[] ErrorReply(int commandId, eReceivePackType ReceivePackType)
		{
			byte[] buffer = InitPack(7,commandId,ReceivePackType);// new byte[7];
			CompletePack(buffer);
			return buffer;
		}
		public static byte[] ErrorReply(eReceivePackType ReceivePackType)
		{
			byte[] buffer = InitPack(7, 0,ReceivePackType);// new byte[7];
			CompletePack(buffer);
			return buffer;
		}

		public static void SetDeviceInfo(IDTContext context)
		{
		
			byte[] versionBuf = new byte[1];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 2, versionBuf, 0, 1);


			byte[] manufactureBuf = new byte[2];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 4, manufactureBuf, 0, 2);
			context.Device.Manufacture = Encoding.UTF8.GetString(manufactureBuf);

			byte[] idBuf = new byte[16];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 6, idBuf, 0, 16);
			context.Device.SN = Encoding.UTF8.GetString(idBuf);


			byte[] parentDeviceIDBuf = new byte[16];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 22, parentDeviceIDBuf, 0, 16);
			context.Device.ParentDeviceID = Encoding.UTF8.GetString(parentDeviceIDBuf);

			byte[] wareVersionBuf = new byte[8];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 38, wareVersionBuf, 0, 8);
			context.Device.WareVersion = Encoding.UTF8.GetString(wareVersionBuf);

			byte[] productTypeBuf = new byte[4];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 46, productTypeBuf, 0, 4);
			context.Device.ProductType = BitConverter.ToString(productTypeBuf).Replace("-", "");

			var ptype = int.Parse(context.Device.ProductType);

			context.Device.eProductType = (eProductType)ptype;


			byte[] authorizeKeyBuf = new byte[32];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 50, authorizeKeyBuf, 0, 32);
			context.Device.AuthorizeKey = Encoding.UTF8.GetString(authorizeKeyBuf);


			byte[] environmentBuf = new byte[1];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 82, environmentBuf, 0, 1);
			context.Device.Environment = Encoding.UTF8.GetString(environmentBuf);
		}

		public static bool CheckHeadAndTail(IContext context)
		{
			if (CheckHead(context) &&CheckTail(context))
			{
				return true;
			}
			return false;
		}

		public static bool CheckHead(IContext context)
		{
			if (context.CurrentPack.HeaderBuffer[0] == Head[0] && context.CurrentPack.HeaderBuffer[1] == Head[1])
			{
				return true;
			}
			return false;
		}

		public static bool CheckTail(IContext context)
		{
			if (context.CurrentPack.TailBuffer[0] == Tail[0] && context.CurrentPack.TailBuffer[1] == Tail[1])
			{
				return true;
			}
			return false;
		}

		public static bool  CalculateChecksum(IContext context)
		{
			int checksum = 0;
			foreach (byte chData in context.CurrentPack.CheckBuffer)
			{
				checksum += chData;
			}
			checksum &= 0xff;
			return checksum ==context.CurrentPack.CRC;
			
		}
		#endregion
		private static void CompletePack(byte[] buffer)
		{
			if (buffer==null)
			{
				throw new ArgumentException("buffer 不能为空!");
			}
			buffer[buffer.Length - 3] = (byte)buffer.CalculateChecksum(buffer.Length - 3);
			Array.Copy(Common.Tail, 0, buffer, buffer.Length - 2, 2);
		}
	}
}
